home *** CD-ROM | disk | FTP | other *** search
/ CD ROM Paradise Collection 4 / CD ROM Paradise Collection 4 1995 Nov.iso / program / swags_z.zip / STRINGS.SWG / 0022_A Complete String Library.pas < prev    next >
Pascal/Delphi Source File  |  1993-07-16  |  25KB  |  612 lines

  1. (*
  2.     TURBO PASCAL LIBRARY 2.0
  3.     STRINGS unit: Extended string-handling routines
  4. *)
  5.  
  6. UNIT STRINGS;
  7.  
  8. { THESE FILES ARE XX34 AT THE BOTTOM OF THE LISTING }
  9.  
  10. {$L SUCASE}
  11. {$L SUTRIM}
  12. {$L SUPAD}
  13. {$L SUTRUNC}
  14. {$L SUCNVRT}
  15. {$L SUMISC}
  16.  
  17. {$V-}
  18.  
  19. INTERFACE
  20.  
  21. TYPE
  22.     FormatConfigRec =   RECORD
  23.                             Fill,               { Symbol for padding }
  24.                             Currency,           { Floating currency sign }
  25.                             Overflow,           { Overflow indicator }
  26.                             FracSep:    CHAR;   { Int/frac seperator }
  27.                         END;
  28.  
  29.  
  30. CONST
  31.     UCaseLetters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
  32.     LCaseLetters = 'abcdefghijklmnopqrstuvwxyz';
  33.     Letters = UCaseLetters+LCaseLetters;
  34.     DecDigits = '0123456789';
  35.     HexDigits = '0123456789ABCDEF';
  36.     OctDigits = '01234567';
  37.     BinDigits = '01';
  38.  
  39.     { Format symbol record }
  40.     FormatConfig: FormatConfigRec =
  41.             (Fill: '*'; Currency: '$'; Overflow: '?'; FracSep: '-');
  42.  
  43.  
  44.  
  45. FUNCTION LoCase(ch: CHAR): CHAR;
  46. FUNCTION UpperCase(s: STRING): STRING;
  47. FUNCTION LowerCase(s: STRING): STRING;
  48. FUNCTION DuplChar(ch: CHAR; count: BYTE): STRING;
  49. FUNCTION DuplStr(s: STRING; count: BYTE): STRING;
  50. FUNCTION TrimL(s: STRING): STRING;
  51. FUNCTION TrimR(s: STRING): STRING;
  52. FUNCTION PadL(s: STRING; width: BYTE): STRING;
  53. FUNCTION PadR(s: STRING; width: BYTE): STRING;
  54. FUNCTION TruncL(s: STRING; width: BYTE): STRING;
  55. FUNCTION TruncR(s: STRING; width: BYTE): STRING;
  56. FUNCTION JustL(s: STRING; width: BYTE): STRING;
  57. FUNCTION JustR(s: STRING; width: BYTE): STRING;
  58. FUNCTION JustC(s: STRING; width: BYTE): STRING;
  59. FUNCTION Precede(s,target: STRING): STRING;
  60. FUNCTION Follow(s,target: STRING): STRING;
  61. FUNCTION Break(VAR s: STRING; d: STRING): STRING;
  62. FUNCTION Span(VAR s: STRING; d: STRING): STRING;
  63. FUNCTION Replace(s,srch,repl: STRING): STRING;
  64. FUNCTION Remove(s,srch: STRING): STRING;
  65. FUNCTION StripBit7(s: STRING): STRING;
  66. FUNCTION FileSpecDefault(s,path,name,extn: STRING): STRING;
  67. FUNCTION HexStr(n: WORD; count: BYTE): STRING;
  68. FUNCTION OctStr(n: WORD; count: BYTE): STRING;
  69. FUNCTION BinStr(n: WORD; count: BYTE): STRING;
  70. FUNCTION Format(n: REAL; form: STRING): STRING;
  71.  
  72.  
  73. IMPLEMENTATION
  74.  
  75. USES
  76.     DOS;
  77.  
  78.  
  79. FUNCTION LoCase(ch: CHAR): CHAR; EXTERNAL;
  80. FUNCTION UpperCase(s: STRING): STRING; EXTERNAL;
  81. FUNCTION LowerCase(s: STRING): STRING; EXTERNAL;
  82. FUNCTION DuplChar(ch: CHAR; count: BYTE): STRING; EXTERNAL;
  83.  
  84.  
  85. FUNCTION DuplStr(s: STRING; count: BYTE): STRING;
  86.  
  87.     VAR
  88.         ds: STRING;
  89.         i:  BYTE;
  90.  
  91.     BEGIN
  92.         ds:='';
  93.         FOR i:=1 TO count DO
  94.             ds:=CONCAT(ds,s);
  95.         DuplStr:=ds;
  96.     END;
  97.  
  98.  
  99. FUNCTION TrimL(s: STRING): STRING; EXTERNAL;
  100. FUNCTION TrimR(s: STRING): STRING; EXTERNAL;
  101. FUNCTION PadL(s: STRING; width: BYTE): STRING; EXTERNAL;
  102. FUNCTION PadR(s: STRING; width: BYTE): STRING; EXTERNAL;
  103. FUNCTION TruncL(s: STRING; width: BYTE): STRING; EXTERNAL;
  104. FUNCTION TruncR(s: STRING; width: BYTE): STRING; EXTERNAL;
  105.  
  106.  
  107. FUNCTION JustL(s: STRING; width: BYTE): STRING;
  108.  
  109.     BEGIN
  110.         JustL:=PadR(TruncR(TrimL(TrimR(s)),width),width);
  111.     END;
  112.  
  113.  
  114. FUNCTION JustR(s: STRING; width: BYTE): STRING;
  115.  
  116.     BEGIN
  117.         JustR:=PadL(TruncL(TrimL(TrimR(s)),width),width);
  118.     END;
  119.  
  120.  
  121. FUNCTION JustC(s: STRING; width: BYTE): STRING;
  122.  
  123.     BEGIN
  124.         s:=TruncR(TrimL(TrimR(s)),width);
  125.         IF LENGTH(s)>=width THEN
  126.             JustC:=s
  127.         ELSE
  128.             JustC:=PadR(CONCAT(DuplChar(#32,(width-LENGTH(s)) DIV 2),s),width);
  129.     END;
  130.  
  131.  
  132. FUNCTION Precede(s,target: STRING): STRING;
  133.  
  134.     VAR
  135.         i:  BYTE;
  136.  
  137.     BEGIN
  138.         i:=POS(target,s);
  139.         IF i=0 THEN             { Return entire string if target not found }
  140.             Precede:=s
  141.         ELSE
  142.             Precede:=COPY(s,1,i-1);
  143.     END;
  144.  
  145.  
  146. FUNCTION Follow(s,target: STRING): STRING;
  147.  
  148.     VAR
  149.         i:  BYTE;
  150.  
  151.     BEGIN
  152.         i:=POS(target,s);
  153.         IF i=0 THEN             { Return null string if target not found }
  154.             Follow:=''
  155.         ELSE
  156.             Follow:=COPY(s,i+LENGTH(target),255);
  157.     END;
  158.  
  159.  
  160. FUNCTION Break(VAR s: STRING; d: STRING): STRING;
  161.  
  162.     VAR
  163.         i,j:    BYTE;
  164.         f:      BOOLEAN;
  165.  
  166.     BEGIN
  167.         i:=0;                                   { Index to input string }
  168.         f:=FALSE;                               { Set when delim. found }
  169.         WHILE (i<LENGTH(s)) AND (NOT(f)) DO     { For each char. in input }
  170.             BEGIN
  171.                 INC(i);
  172.                 j:=1;                           { Index to delim. string }
  173.                 WHILE (j<=LENGTH(d)) AND (NOT(f)) DO { Scan for each delim. }
  174.                     IF s[i]=d[j] THEN
  175.                         f:=TRUE
  176.                     ELSE
  177.                         INC(j);
  178.             END;
  179.         IF NOT(f) THEN
  180.             INC(i);
  181.         Break:=COPY(s,1,i-1);           { Return sub-string up to delimiter }
  182.         s:=COPY(s,i,255);               { and remove from the input string }
  183.     END;
  184.  
  185.  
  186. FUNCTION Span(VAR s: STRING; d: STRING): STRING;
  187.  
  188.     VAR
  189.         i,j:    BYTE;
  190.         f:      BOOLEAN;
  191.  
  192.     BEGIN
  193.         i:=0;                               { Index to input string }
  194.         f:=FALSE;
  195.         WHILE (i<LENGTH(s)) AND (NOT(f)) DO { For each char. in input }
  196.             BEGIN
  197.                 INC(i);
  198.                 FOR j:=1 TO LENGTH(d) DO    { Check for specified chars. }
  199.                     IF s[i]=d[j] THEN
  200.                         f:=TRUE;
  201.                 f:=NOT(f);
  202.             END;
  203.         IF NOT(f) THEN
  204.             INC(i);
  205.         Span:=COPY(s,1,i-1);                { Return span of specified chrs }
  206.         s:=COPY(s,i,255);                   { and remove from the input }
  207.     END;
  208.  
  209.  
  210.  
  211. FUNCTION Replace(s,srch,repl: STRING): STRING;
  212.  
  213.     VAR
  214.         i,j:    BYTE;
  215.         f:      BOOLEAN;
  216.  
  217.     BEGIN
  218.         IF LENGTH(srch)>LENGTH(repl) THEN       { Ignore search chrs. }
  219.             srch[0]:=CHR(LENGTH(repl));         { without replacements }
  220.         FOR i:=1 TO LENGTH(s) DO                { For each char. in input }
  221.             BEGIN
  222.                 j:=1;
  223.                 f:=FALSE;                       { Scan all search characters }
  224.                 WHILE (j<=LENGTH(srch)) AND (NOT(f)) DO
  225.                     IF s[i]=srch[j] THEN
  226.                         BEGIN
  227.                             s[i]:=repl[j];      { Replace if found }
  228.                             f:=TRUE;
  229.                         END
  230.                     ELSE
  231.                         INC(j);
  232.             END;
  233.         Replace:=s;
  234.     END;
  235.  
  236.  
  237. FUNCTION Remove(s,srch: STRING): STRING;
  238.  
  239.     VAR
  240.         i,j:    BYTE;
  241.  
  242.     BEGIN
  243.         FOR i:=1 TO LENGTH(srch) DO     { For each search character }
  244.             REPEAT
  245.                 j:=POS(srch[i],s);      { Repeat search in input string & }
  246.                 IF j<>0 THEN            { delete if found until no more }
  247.                     DELETE(s,j,1);
  248.             UNTIL j=0;
  249.         Remove:=s;
  250.     END;
  251.  
  252.  
  253. FUNCTION StripBit7(s: STRING): STRING; EXTERNAL;
  254.  
  255.  
  256. FUNCTION FileSpecDefault(s,path,name,extn: STRING): STRING;
  257.  
  258.     VAR
  259.         d:  DirStr;
  260.         n:  NameStr;
  261.         e:  ExtStr;
  262.  
  263.     BEGIN
  264.         FSplit(s,d,n,e);        { Split file spec. into path, name, & ext. }
  265.         IF LENGTH(d)=0 THEN     { For each field, add default if none }
  266.             d:=path;
  267.         IF LENGTH(n)=0 THEN
  268.             n:=name;
  269.         IF LENGTH(e)=0 THEN
  270.             e:=extn;
  271.         FileSpecDefault:=CONCAT(d,n,e);
  272.     END;
  273.  
  274.  
  275. FUNCTION HexStr(n: WORD; count: BYTE): STRING; EXTERNAL;
  276. FUNCTION OctStr(n: WORD; count: BYTE): STRING; EXTERNAL;
  277. FUNCTION BinStr(n: WORD; count: BYTE): STRING; EXTERNAL;
  278.  
  279.  
  280. FUNCTION Format(n: REAL; form: STRING): STRING;
  281.  
  282.     VAR
  283.         s1,s2:                  STRING;
  284.         width,dp,sign,i,j:      BYTE;
  285.         pad,currency:           CHAR;
  286.         blank,zero,left,paren,
  287.         comma,adjust,reduce:    BOOLEAN;
  288.         x:                      INTEGER;
  289.  
  290.  
  291.     { Reduce fraction to lowest possible denominator }
  292.  
  293.     PROCEDURE ReduceFraction(VAR num,denom: BYTE);
  294.  
  295.         VAR
  296.             i:  BYTE;
  297.  
  298.         BEGIN
  299.             FOR i:=denom DOWNTO 2 DO
  300.                 IF ((num MOD i)=0) AND ((denom MOD i)=0) THEN
  301.                     BEGIN
  302.                         num:=num DIV i;
  303.                         denom:=denom DIV i;
  304.                     END;
  305.         END;  { ReduceFraction }
  306.  
  307.  
  308.     BEGIN  { Format }
  309.         form:=UpperCase(form);
  310.         s1:=Break(form,CONCAT(DecDigits,':'));      { Get leading options }
  311.         IF POS('A',s1)<>0 THEN                      { Absolute value, no sign }
  312.             n:=ABS(n);
  313.         blank:=POS('B',s1)<>0;                      { Blank if zero }
  314.         zero:=POS('Z',s1)<>0;                       { Zero-fill/zero-show }
  315.         left:=POS('L',s1)<>0;                       { Left justify }
  316.         comma:=(POS(',',s1)<>0) OR (POS('C',s1)<>0);    { Commas }
  317.         reduce:=POS('R',s1)=0;                      { No reduction }
  318.         paren:=POS('P',s1)<>0;                      { Negative in parenth. }
  319.         IF POS('+',s1)<>0 THEN                      { Check leading + }
  320.             sign:=1
  321.         ELSE
  322.             sign:=0;
  323.         IF POS('*',s1)<>0 THEN                      { Set fill character }
  324.             pad:='*'
  325.         ELSE
  326.             IF POS('F',s1)<>0 THEN
  327.                 pad:=FormatConfig.Fill
  328.             ELSE
  329.                 pad:=' ';
  330.         IF POS('$',s1)<>0 THEN                      { Set currency symbol }
  331.             currency:=FormatConfig.Currency
  332.         ELSE
  333.             currency:=#0;
  334.         s1:=Break(form,CONCAT('+- ',#9));           { Get width:decimals }
  335.         IF POS('-',form)<>0 THEN                    { Check trailing +/- sign }
  336.             sign:=3;
  337.         IF POS('+',form)<>0 THEN                    
  338.             sign:=2;
  339.  
  340.         s2:=Follow(s1,':');             { s2 is decimals }
  341.         s1:=Precede(s1,':');            { s1 is width }
  342.         VAL(s1,width,x);
  343.         IF x<>0 THEN                    { Default width 12 }
  344.             width:=12;
  345.         IF COPY(s2,1,1)='/' THEN        { Use vulgar fractions }
  346.             BEGIN
  347.                 n:=ABS(n);                          { Force absolute value }
  348.                 sign:=0;                            { Disable sign display }
  349.                 DELETE(s2,1,1);
  350.                 VAL(s2,i,x);
  351.                 IF (x<>0) OR (i<2) OR (i>99) THEN   { Default resolution 1/2 }
  352.                     i:=2;
  353.                 j:=ROUND(FRAC(n)/(1.0/i));          { Calculate fraction }
  354.                 adjust:=(j=i);                      { Allow for rounding }
  355.                 IF adjust THEN
  356.                     j:=0;
  357.                 IF reduce THEN                      { Reduce fraction }
  358.                     ReduceFraction(j,i);
  359.                 STR(j,s1);
  360.                 STR(i,s2);
  361.                 IF j=0 THEN                         { Format fraction }
  362.                     s2:=DuplChar(pad,6)
  363.                 ELSE
  364.                     BEGIN
  365.                         s2:=CONCAT(s1,'/',s2);
  366.                         IF (INT(n)=0) AND NOT(zero) THEN
  367.                             s2:=CONCAT(pad,s2)
  368.                         ELSE
  369.                             s2:=CONCAT(FormatConfig.FracSep,s2);
  370.                         s2:=CONCAT(s2,DuplChar(pad,6-LENGTH(s2)));
  371.                     END;
  372.                 IF (INT(n)=0) AND NOT(zero) AND (j<>0) THEN
  373.                     s1:=s2
  374.                 ELSE
  375.                     BEGIN                           { Format integral part }
  376.                         IF adjust THEN
  377.                             STR(INT(n)+1:0:0,s1)
  378.                         ELSE
  379.                             STR(INT(n):0:0,s1);
  380.                         s1:=CONCAT(s1,s2);
  381.                     END;
  382.                 zero:=FALSE;                        { Disable zero-fill }
  383.             END
  384.         ELSE
  385.             BEGIN                       { Use decimal fractions }
  386.                 VAL(s2,dp,x);               { Get number of decimal places }
  387.                 IF x<>0 THEN                { Default to zero decimals }
  388.                     dp:=0;
  389.                 STR(ABS(n):0:dp,s1);
  390.             END;
  391.  
  392.         IF comma THEN                   { Insert commas if necessary }
  393.             BEGIN
  394.                 s2:=Span(s1,DecDigits);
  395.                 i:=(LENGTH(s2)-1) DIV 3;    { i is no. of commas to insert }
  396.                 FOR j:=1 TO i DO
  397.                     INSERT(',',s2,LENGTH(s2)-(j-1)-(j*3-1));
  398.                 s1:=CONCAT(s2,s1);
  399.             END;
  400.         IF currency<>#0 THEN            { Add floating currency symbol }
  401.             s1:=CONCAT(currency,s1);
  402.         IF paren THEN                   { Add signs as required }
  403.             BEGIN
  404.                 IF n<0 THEN
  405.                     s1:=CONCAT('(',s1,')')
  406.                 ELSE
  407.                     IF NOT(left) THEN
  408.                         s1:=CONCAT(s1,' ');
  409.             END
  410.         ELSE
  411.             CASE sign OF
  412.                 0:  IF n<0 THEN                 { Leading - }
  413.                         s1:=CONCAT('-',s1);
  414.                 1:  IF n<0 THEN                 { Leading + }
  415.                         s1:=CONCAT('-', s1)
  416.                     ELSE
  417.                         s1:=CONCAT('+',s1);
  418.                 2:  IF n<0 THEN                 { Trailing + }
  419.                         s1:=CONCAT(s1,'-')
  420.                     ELSE
  421.                         s1:=CONCAT(s1,'+');
  422.                 3:  IF n<0 THEN                 { Trailing - }
  423.                         s1:=CONCAT(s1,'-')
  424.                     ELSE
  425.                         IF NOT(left) THEN
  426.                             s1:=CONCAT(s1,' ');
  427.             END;
  428.         WITH FormatConfig DO
  429.             IF LENGTH(s1)>width THEN            { Check for field overflow }
  430.                 Format:=DuplChar(Overflow,width)
  431.             ELSE
  432.                 IF blank AND
  433.                 (LENGTH(Remove(s1,CONCAT('0. ()+-*',Fill,Currency)))=0) THEN
  434.                     Format:=DuplChar(#32,width) { Blank if rounded=zero }
  435.                 ELSE
  436.                     IF zero THEN                { Pad field to width }
  437.                         BEGIN
  438.                             s2:=Break(s1,DecDigits);
  439.                             Format:=CONCAT(s2,DuplChar('0',
  440.                                         width-(LENGTH(s2)+LENGTH(s1))),s1);
  441.                         END
  442.                     ELSE
  443.                         IF left THEN
  444.                             Format:=CONCAT(s1,DuplChar(pad,width-LENGTH(s1)))
  445.                         ELSE
  446.                             Format:=CONCAT(DuplChar(pad,width-LENGTH(s1)),s1);
  447.     END;  { Format }
  448.  
  449.  
  450. END.
  451.  
  452. (*
  453.  
  454. The following contains the ASM and OBJ files needed for this unit.
  455.  
  456. Do the following :
  457.  
  458. 1.  Cut the code out to another file.  Call it STRASM.XX
  459. 2.  Execute -> XX3401 D STRASM.XX.  The file STRASM.ZIP will be created.
  460. 3.  Unzip to have OBJ and ASM files needed.
  461.  
  462. ------------------    CUT HERE --------------------------
  463.  
  464. *XX3401-007122-160793--68--85-58879------STRASM.ZIP--1-OF--2
  465. I2g1--E++U+6+BRwjVcn7M7VxU6++1wC+++8++++IpJ1EJB39Y3HHSpLHLCPA-0xSwPz
  466. MGyRh3CGgRpC1gsZTAKa6kC1QCAaYkBpZ6G46+cWbTHL3m360EXWBeRqcggmW5qvSfjv
  467. N-z-oyKjDQo-JwKuWU-NaeRuLq-qA-aDqZzeEINUGyBvYaMVXS4CLiMF4Mz46qVXKXsm
  468. 0viq9Fykvpbq+gxvzRjSfffUnb-se2kzn9fvPnH9tbMusv3pln0PixVQf2nPVpD5Avey
  469. 8gPfJT4xXiTQgTg-QUcSg0GdhMMgLSlXIs4puteSS2HCeLXYuLFdCpbPiawtBW-OAj-q
  470. SpBkgJGxRw76W0stMf0x0R7UmoU8X272Tt-oTwgFmDQwj+wW2XASHqHImBFnx16iVysQ
  471. kr39eqp+ictUEFWYVCJd1A5ZNIem18tGSUQN0vOrzM1udbxD5EnqytFV10fekiWf0UMd
  472. SyeS1AOaFOvTwcl-S+Il9H0174F-pALud+ZvT6makt5CxWHSud0rso5hDNggNLbKVQqH
  473. d33Is2IRXnXcz2b5sOJUhcwxXqGAdeFJ9Zbj0WFBIWDDx9ghNBe48thfDdbDBDaO5oro
  474. SHOjNjxRzR1TuVZ9kzWOIm8s2NGAFsxXhZBnpyRoirgftvBcT3T-fdFBH5VVF7z1JFfQ
  475. 2IVc41CGxYQm72e-10m2m36A9Y9UyVuQOyvvksgeYghV0xwthjW7knX7OkMYQ8O+Axdk
  476. owZ32wv2QuC2cnYPkhCFoQyCXdFnP3roH4eNu5tJecX2pym4nulgx1TJACV9FJx8sq2B
  477. yVQTZSGVCgBy3Sff+tDQ3dzonJYpYlzYIDUqH00WB0bJ6MyWFqvO6sQQstaoOg2u286s
  478. L9eab+Gv0JRH2+OoOnMQvCSkRYawJRicjGT4mL7+ioG4fI5Zc2oWgSxUHLOtWVh-u0Sj
  479. q3lmLJHnAmVspq54G7cBL50iJCh8yv4f8mxEDAE7SMbWBKjChTXoJT3S3SzTJvkRTucp
  480. NSHj3SzgXlJjxpxfzsTWhLKZJfnqzuTWDNMdMT4Sjzs3I2g1--E++U+6+BNwjVfCAxyp
  481. EUA++0cC+++8++++IpJIIYZB9Y3HHSpLHKzPC-0x-z-za2i-LOkGl5MGcD6Z2eZBJB0G
  482. EAehqw+5BOMP6PPYZSGUuOwjeExLAGYtKTGoK3pcYC9AawTVSz62LXvVXBcy--N13U5W
  483. qhGWbq3oRXssIRvAsUpwLIT7MkuPR9ZPww57s+ECrr71scVltfYVg70urUonhLgDRkPK
  484. XRk6JpT4Q1lGpxzNfWT5sIXaFHtqqejAiNYuLUWTT6fJjFNXguZs5n3HPZFT69ucbqZ+
  485. nKnW6Z2KROT28+Qeoujoz1rnICXuLZYfUHxmgmvznyN5-uJf5WrXt3h1nmd9Bt+LaNWG
  486. OQf2PI1IFqIuWyfEgZgtqc4uBjIzEfJag+1INk8A3v1PWhnFzOC+2KosPBAs8LXKbEZf
  487. C0CMJITW4ZUS-kEVVHgvyCheIKQ8N3WlpqEi30b2mLNLv4hKkXZJC5kMPbWyO6Rna6b9
  488. QCaiu6i50CtVNqu661dqF5VvLV4Ghv8gST8hS60jnkLLRFJaBbEz2vUFb7TZbpNkarVl
  489. +aXS1FAFkm9ewhmbpT8hUKvJNRR1BNBRQBVXj8ofCyqhf+40WM46BVF8hwyEfif1zJIK
  490. pi1yUCNTt5VxHGtuUAIfG5PfRIBJ4LZk6XMBnHSHbj1j-RkzF3ZofqpkB8oiWIKAwIVT
  491. s+CLxmHBedifeOcK8+3kp7jUjKOjtnFvlqK7crO7q8YDYbGJu8seJ+MgyTrNmqPJxOYT
  492. pBa45NGZgiSDYTOVfcbRyXEgHvD2DatXNu3zt5U2xWEh4jltYKNQBYtJUteo6EBd4cgu
  493. UKnJncEH09AcmJQwUsljcXVNWZzdOewRgUFHozMCAyzgyQ6sD6+7g-9iOwEVe1XLGaWn
  494. dVBmucHZS84OUyDVE4T8oZdTsJfo1OtJN34wvfQh0jzPpiyn9FPWLXysMys0SUnaW9AQ
  495. gMuKEczVe26TcQP0i42OnPL-diYHVsfZRNGzo7nzihlTe57zL7tPQeyex820hoIAikj3
  496. k-gFyw4nh3z039qzv7TAjamjYQna+sNpTg1g9ySyPQsUszzgsckjilgFRnPWzbP842yF
  497. E3T+BgrX6YuHTqArtJTFzanmYet9wzSv+hKski3T7X5DR4sVtiLoHp-9+kEI++6+0+1J
  498. T9sOCDOSb+E1++-g1E++0E+++3BJI2329Y3HHSpLLKyPA-FxfxHzQ3waPFe9aYme7f77
  499. -NiZP+sUaumdeXnEs9Gc8KFweBizbloUHMAVKPjhOHn2kiOSSyu5vp44wDHl7xFokHAM
  500. AUUEquE4jMF-vyHsODR99kUVmxAcjc5v70mKzDXcy+VqsKmTK48RC9MDn8SqAq8umbHL
  501. o1B4oUtCHvLyyo5nz7JdCr9h1uFPt47fytFNcv5Zy51VIhmoBFWPXALrWCbGgDY-QILo
  502. H23eMV6PGL8MOD8LGiTBp5mSCAWrLIQ4Gi-pdZSV1y2V0jBP5Ql9rrdHvrOaxW58Pq57
  503. Up0yL0y1y0u1D63glSTF6i7VWGV7G37DE8W9paEAece2bQjJx7dbMzQPZ4QOwu1t165l
  504. 56eJc-XAvq0F-jQQJYYItnlhxsEJyGGMZSKmBGl9-NtDsQforbuMJNsw0GhgRKP9g8Bs
  505. JSFJOVFkJUa5Ry5uUxYqbAJoj6N9Wfk9fos2aacGtLHKGAF6709ZrkiStLId-2RVo+GP
  506. ifE2CxTESITGdtfUdYfuJwtLA2xKDm3NpAm1A2ltZXLV2A4ehgPAP4snrqIah1x1wBAU
  507. nVMwVGKDPoG6axGpls47Nd1qC9M9KO2eUVVvJH+0erbwlGnjzBYNuOhtgvh6i3f62YYb
  508. 5nyJPhjwpRkhdZyNota4G+AkHp7Sko4EpLIEPnp3MWTa6rwZEFEgtnq6YtuguSDh3aJh
  509. NqQEPL0Wu0-eSNqZfBZLPe7shzpZ5bJJylABYnoBrHcao5FnPxzh8PQAEDXg041HVqIR
  510. CxfEQwjKeEOA+cjmP7qC6+t3ETAWXRhFJ3CGKjtuDKpCLgj-bYcAdOPh3knu-kEXHsBc
  511. SMVWIDWj45x1AMVqlSnNQmuBZ7HhARKa7th-CxLER9xUR2wyqo4JoXpPaFsbcGHxSw7o
  512. qAozuC9zGwrSoWTw6bq82y+zwXGcfij9Z8aAu6YqRIcHJYiHIxlTWsHjuh8yRbmyCZqY
  513. IQurbCpFdwAbTAdj6Z5fB5j7U8Se+PzvhoDgAxLU3zhmylREGkA23++0++U+ormy4jzr
  514. Jb1n+U++GEk+++g+++-HJJFGJIt19Y3HHSpKoKfPA-Fx1yETvghUMqtNAUX14Omqv0Ii
  515. WaoYNohLwa+GdHJfvAmK4RjLHsdgG0AtvI9rBfw6R8JnnvauCj6M5bz7b9UFl+t31UMQ
  516. iAEVBn0wTBTjOGj9CZyZb253mmmzUqqlfVxMjxTjkT586A4y4CRVY+-BG--CeBqtzrVr
  517. v2nYNVWBfA5vcFtztEOV5+R1aFh3bbwMdTtYtcQ7T6q6dyxp87rDl5d2PPZFLs+XIERe
  518. 61JrQM02B16D2PPq+t5txHdx3e2YW26Z4ADfmau8A6OTqNfTqy1S7DuPRjPdGaz8MUgD
  519. PAC-3p1hq0fPN4mhk0E1FSe+96bEbcZ1H2fcJ6tifARaoFREAMj4c5xXc6l1jFD2ohJr
  520. kGjRAhUJKQtNqNr7AxEHSpERJq1Rij5P1oghImlVlJuP-Z7qZixerVH2+CQfC2z-1MN9
  521. AtlDPKwDJxHw33tP04Sllljdx0OW20LvIPC8hoQVC681RP-3F-HMp58arPYEhatdg1EI
  522. LSPOuvxc4i8-tLQe5pdotoBH0lbm-G3eGez521NQ4XFHjS-U0lbYLPhej9f0+n+qnLKx
  523. rI4q+OvuCWjmTSamYepDZVshX51--j80Kv+eRfzO8t7KY6YWJENu1LguXIUWGEvvDIbJ
  524. DXGBiR8+3dNXnVYKZp-gM5KTZia8gv8GHRHcALWMsrZhSrS6IDqcSbhEQM3Q5VF3obl2
  525. A6ac0xrT40UjGhOqhSeD2urq57rJdR8MthL4R9qjoS7PQyvjxGXlMtaiYzIMY1kyzGd8
  526. i2DdQOHCnyEWPQnYNQFDxiB6xoQzx49HimJTbiRsCbYdHmyniziHdYvUjuaza8YPnEp5
  527. rVArusHvCcjnrTtjLtMnb9spPcEh-lipYQRtDec1IE6zbKDpfHTL3MB1A2WfYmxT-vwX
  528. DnjqvFP+dzOh3mkhVAymlTN3x68H9XQoGov8R+SzKJZQB37JapHbS49GiCqV4kvzVFgG
  529. rEqDzuH3D1Ktd7WLorw+I2g1--E++U+6+B7wjVfA7sv1RkA++3QG+++9++++IpJ1HZNG
  530. J0t-IorhK3pjqnMITEyEzr-T0amMKjUXG+fZdF8ZK-dYGF1ZnJqF-wKaMu2C4J-IajHL
  531. ZlGJn7Pcf5KlPYCa3xcGRLXisPrbGXe5rGCTNKs0eMCF2o2IidaHjMTFaw5lILRaLBxQ
  532. 2TtOgBSJs0KxVUKXRsFL7OBkktPpVVkT5Fx-3nzA6pyCgnXA+SRN42ykzJJMLOHIaGUU
  533. C1qpViBFzzcfBsnJC-kd5WXlzCqfq7xAzHW5rtDAuxzfM1mPmjY6qyf4zcEcYTdU+uaN
  534. 4sI66D1bAXUfEPYO7-AtaCFEEOXnTLYjNX58kmG4UBlXkS2bOXRYnuIqBFIqiCxnzqSv
  535. pP-zToN2nGagmToPsCGKYsdEIEWZ83g-VN70evLwqo10MZrkMW4YvceE1a49OdOUVdWH
  536. aS94UFfRh5xhajk4yde3IyUTts07UDdKwWYK5q53Wlg0humYYgZyB1GrDfXd9uSLzGbn
  537. FBB4UMI0ss6HiO0CKQe+tjhLwTEePmyB27wMLs7UPPMqM7s-9D8l-UgPgC5UgUiKeaX-
  538. lvML8XlKWxhOhDinbtmQzw299moIxEEJX7BR4BUESWrKTPFToTkDBPtv3soBZS-tXxnF
  539. r8WZteu7Psde8sruO1XrbgaDm-eQ-APwK7Qf+LT3dWOkMbn95MuD7CqVPI-ntdNd9tlM
  540. lyD6lGuAWoq9uaAH0mbid6OIk98w9cLwhLbcsvKddj14+mASOdB1EXcMVS3nye-dycHa
  541. aB5KFBK6384dP+T2ahRkMRVKJsxGbx5yPJImb+KBWWBvNuAGvA9ysn534V7ObmR1AFEY
  542. 0WPB1gwhIv5V65gghasevmE+eoKvJZhkNDbBOoJ7YfOm1Aq-HFUg4J-mjtD7eXeq-Icp
  543. XB5kAXxjldCyWTelZlvM-t83y6syk-OWq-nK05EHyvwFj8-4ADf54w5sFnO0grxR6zVO
  544. zxJZzI6AS5G++LTBungAq0rdLljkyJs5jWddkFyA3ZlLydqbvvrunS43SixzlWtDziOy
  545. wKFZSvp34wdbkhYDQSuipqsNm7uWpUNmJHPqhmUsTqUAL7-848GBoRCnelYiLA5EIXHd
  546. BN4mzCadX-cy3MEhbVARzeHPyBunJATaqnANcU8E9AgJI96UJJJkEkTlz-qKCsyPryGO
  547. JsecGgg1z97fC6xyqTpy6gxXYsz8wyfo3p-9+kEI++6+0+1MT9sOuigk5cM0+++a0E++
  548. 0U+++3BJHIZHEmt-IorBJh3ian+ITMyITvUjYneBHIoq7FBt8FWOA1a+A8ndeXtEuUOo
  549. ***** END OF XX-BLOCK *****
  550.  
  551.  
  552. *XX3401-007122-160793--68--85-04457------STRASM.ZIP--2-OF--2
  553. 106kojPrgu328HN7JKbGz56Zv5hwvj2xBpb+mlJ4USa-Pl-YMA0C4FX-9IkzLMt5zNDf
  554. f2fcPVTbh8Uf86iONHahs3TlKCzcS1ESEFzO0P5BMyEu6N+kQBkZoQz-x23wMmYkM1PH
  555. 7dybwjsvor33b2k3-SFNxj2igNRfqkrVlUggCRQU73fnwsXc6Z2yU1qi0Z4EWYng6++f
  556. wX3O4M5KZCSPHXUL94HhfWALVMvbUZLjRmWBGvV6IVp2vU8GcguN1iNhO9zLbsKG6IFa
  557. ZgGAEg9nssHFIhnIIHVE0nnIr4U28htY7O9dmrhfvnioSlflEJs967F-jMS8lQZDS0fX
  558. LlHqFNMrF0HZPB8mRfEvozwkiPnjczYW3KmWKkuk+ceOvKj4kQggrkunAnMBrilSMfTY
  559. v-cZ6Qj-k162kccK6835H-VSj4dKZ-HWeaCsczaKdT1kVx3VaUVf-ZP0VKKQJoyoTCP8
  560. 8oQP4KTXhEy8JVdOmRjToCO5W3RLS57Keuw1KbJRB8FLMDgbtSaYCKd5kIQzvXTDVu3y
  561. 0ymkWJzY5fNRmpQB3129njW9g19PalaPkoLJSSa2eR0ClWKYqHPxK7GDL6i5X25l-1FC
  562. odQ8RMot5Vqgzbwtffj7IgkfP9Ji7AuESpcrKYEbXFinz7ENztKt2RPiW5Cj226oP7jR
  563. yMwzmFiActk-zDcnAy-UqdDaDr9ZJDM0xeknhsUWQzeP5Hh8ygZmfHNWPLuxIe4cKjch
  564. Qyyan-VxlSBVfnKte5SUfU8qWh82H8dVcKfUJkuGjXKvER9zKw0z2xK+sRzPyT6LI2g1
  565. --E++U+6++ZxjVeTUjEtok++++U-+++8++++IpJ1EJB39Yx0GajUMS+81bJq15PJQknq
  566. bRuVkA1+237OZ7Gjs3VQb7ePZ7BOd8+EZZdIb7aTdq0cNq1MoG52sD1mSgoy8GFxdVrA
  567. E24TOIkA1-bHq-VMbDpRL3pbg1AsF12kAH6SbW1+kA16uSATvVc2oa58k3+nUFQclCPX
  568. 1y61fJk8IF6O2+-F+iHBuq-VQ3X2C53-5+AX+oBoN6GBMl4PHJEt2sx0MD1doCsrQYT9
  569. q6vIQTrdsX3uiyElrlePF8-wJHaHmjpJXnv7lttWMQ0a04s6H33h3x1J7E-EGkA23++0
  570. ++U+15qy4XV5qhLL++++yE++++c+++-HJJFGGIoiHo78Oy-Vs+cC1EbmxBJn1DMhvp-U
  571. M4+68Gp8mZRk90tCnIr8GGpGI+V99GfCnAxHABEnACnc247kS5ahNdwIYXul1aOUcAwo
  572. 7UO4X4Zg10nCzWuifXDM4FmG4NUM4LRBs43UM4E38TM-4bwBkEomNa0Mqw50s906QS80
  573. R+N4-cPEvXRmFwjMXhFlzSayjuPfVB3Pxuu9XoLKq0WIgBVkZf9xCzLcwqjKJTxCTZuW
  574. pW2i5ri8-Ib9rmsScvSDSNYzkdGnDzeepg5vaUB6i15zz9k2fDt03x0N7E-EGkA23++0
  575. ++U+1rqy4ifHluP7++++vE++++Y+++-HJJ--F0tDEYdfs4PU1+sBQ5HFQknqTR0VkA1+
  576. 237OZ7Gjs3VQb7ePZ7BOd8+EZZdIb7aTdq0cNq1MoG56sD1mOgoy8MGqVUtac7XDB0M4
  577. VcldP+kgnjsifesnq-YQcVaM4-YDHS-aM4-Y+Ofp+Fdi1yQ3uH2kQ5SkA1UgMdms67u-
  578. YM2VhDiBrB2mXWBpDBpyP2NjiyzzKPCeus9JWH7ChEtyfFAP31ujuXdZxDPn2jbMIql6
  579. efhsU6cjCU9JTps0paZp0e9Z32U9KD579e1XGU-EGkA23++0++U+2bqy4ibgE-T8++++
  580. vE++++g+++-HJJFGJIt19Yx0GajUNS+C1Uo70jJnpbAAxZLhI4-UM+Ud9If8Jr+g9YvB
  581. HQd79J7E02gh8gvAnpAkp1AkvCUENb-sSPZablGmliARn2-FbqZA1+kNoxUMK7nxLJlR
  582. Nv+nC+EnA12mbdf+mw1+m+NKvECoc+K75uH9k-1MkQ9Ug6Vlsc7k-YM4Vh1iBr75mnWC
  583. pD3oiv2NDSbWALffxgTeM-39xw5L9Bcba1yiuXvlaCbn2jbMIql6WjygALfGvQRaxBPe
  584. F-3Hpkap1Ztri8eC9e11GU-EGkA23++0++U+3Lqy4i0NFEo5+E++9k2+++g+++-HJIBC
  585. JZ7I9Yx0GaqDAIX1M--4jnw7GR24-rLdx+z3AGGCsd+O+kcpVGMB1fcI+Ude6R3BWcjo
  586. pmmuZ6vWq2Zk3l3-QJCbfbKmuW-C1cdLeh1-tS+Rvr5QbctFjy7sMHYk0jtGLb++kItQ
  587. fT30YYGPpMoctXmAsaGxhgIhkvG246Txz9-vYFgCPsFAqq7H+hOO8VGbBCyu9ErqDWH4
  588. KYQukBGtFQwDmWi+AS+3RtaM1hM5L560MUgc0ULq8HgyCE+18iZfuebHPqaMiOuDH+bx
  589. 8GRzTdofuJJy94jCngGGcfIPbQRScxBxKPpHzUYayc3AUNMpzxHrMTLLauHYn0HtjdR6
  590. rtRh4fTRXvuMCOHLhbw+I2g1--E++U+6+-ZxjVfyc8wEm++++BE++++8++++IpJBGJB1
  591. 9Yx0GajUMS+81jLp15PKQknqPSxEM4-U00YhGgdLQ0kiHgpBmYYhIZ+6GmoengnDIn1I
  592. An1gu--WQ5VtcqOT376yZEtac81DB0M4VcldP+kgnjsifesnq-YQn-aM4-aTHF-UM41Y
  593. 1+s7wUlkwUklZq7Ua18-5mX2sF6OsCDgsFU2h7GpUsL-MF5Xl+LK16kA185RPsvIQLKv
  594. gTpNpLL0uCpXpasrXgyfMYylU4HYXdOl+KKvS6nSzZbma4qBGjqeFvzYEN65is+i8+2+
  595. I2g-+VE+3++0++U+prmy4XAZUa5q+U++Dks+++c++++++++++E+U+++++++++3BJEo3H
  596. FGt-IopEGk203++I++6+0+1KT9sOnXDThI61+++e1U++0U+++++++++-+0+++++S+k++
  597. IpJIIYZB9Y3HHJ-9+E6I+-E++U+6+BJwjVcsxduQ-+A++4kB+++7++++++++++2+6+++
  598. +6U4++-HJJ--F0t-IopEGk203++I++6+0+1HT9sOzzRKQDA0++-71+++0k+++++++++-
  599. +0++++0n0E++IpJIIZJCEmt-IopEGk203++I++6+0+1GT9sOn0SCkrQ1++-L2U++0k++
  600. +++++++-+0++++1D1+++IpJ1HZNGJ0t-IopEGk203++I++6+0+1MT9sOuigk5cM0+++a
  601. 0E++0U+++++++++-+0++++-j2+++IpJBGJB19Y3HHJ-9+E6I+-E++U+6++ZxjVeTUjEt
  602. ok++++U-+++8++++++++++2+6++++-oH++-HJIB-IoIiHo78I2g-+VE+3++0++U+15qy
  603. 4XV5qhLL++++yE++++c++++++++++E+U++++4-E++3BJJ377HGtDEYdEGk203++I++6+
  604. 0++DTPsOuhD5dgY+++1h++++0E+++++++++-+0+++++L3E++IpJEEIEiHo78I2g-+VE+
  605. 3++0++U+2bqy4ibgE-T8++++vE++++g++++++++++E+U++++-lM++3BJJ37JHYAiHo78
  606. I2g-+VE+3++0++U+3Lqy4i0NFEo5+E++9k2+++g++++++++++E+U++++yVM++3BJEotK
  607. IZEiHo78I2g-+VE+3++0++U+4Lqy4juUfl16++++p+++++c++++++++++E+U++++8VU+
  608. +3BJHIZHEmtDEYdEGkI4++++++k+1+0W+U++4VY+++++
  609. ***** END OF XX-BLOCK *****
  610.  
  611.  
  612.